package edu.jhu.secondhome.database.beans;

import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

/**
 * Database Bean: User
 */
public class User {

  private String email;
  private String password;
  private String firstName;
  private String lastName;
  private String phoneNumber;
  private String currentAddress;
  private String billingAddress;
  private String creditCardNum;
  private String creditCardExpMonth;
  private String creditCardExpYear;
  private String creditCardSecCode;
  private boolean admin;

  public User() { }

  public User(String email, String password, String firstName,
      String lastName, String phoneNumber, String currentAddress,
      String billingAddress, String creditCardNum,
      String creditCardExpMonth, String creditCardExpYear,
      String creditCardSecCode, boolean admin) {
    this.email = email;
    this.password = password;
    this.firstName = firstName;
    this.lastName = lastName;
    this.phoneNumber = phoneNumber;
    this.currentAddress = currentAddress;
    this.billingAddress = billingAddress;
    this.creditCardNum = creditCardNum;
    this.creditCardExpMonth = creditCardExpMonth;
    this.creditCardExpYear = creditCardExpYear;
    this.creditCardSecCode = creditCardSecCode;
    this.admin = admin;
  }

  public String getEmail() {
    return email;
  }

  public void setEmail(String email) {
    this.email = email;
  }

  public String getPassword() {
    return password;
  }

  public void setPassword(String password) {
    this.password = password;
  }

  public String getFirstName() {
    return firstName;
  }

  public void setFirstName(String firstName) {
    this.firstName = firstName;
  }

  public String getLastName() {
    return lastName;
  }

  public void setLastName(String lastName) {
    this.lastName = lastName;
  }

  public String getPhoneNumber() {
    return phoneNumber;
  }

  public void setPhoneNumber(String phoneNumber) {
    this.phoneNumber = phoneNumber;
  }

  public String getCurrentAddress() {
    return currentAddress;
  }

  public void setCurrentAddress(String currentAddress) {
    this.currentAddress = currentAddress;
  }

  public String getBillingAddress() {
    return billingAddress;
  }

  public void setBillingAddress(String billingAddress) {
    this.billingAddress = billingAddress;
  }

  public String getCreditCardNum() {
    return creditCardNum;
  }

  public void setCreditCardNum(String creditCardNum) {
    this.creditCardNum = creditCardNum;
  }

  public String getCreditCardExpMonth() {
    return creditCardExpMonth;
  }

  public void setCreditCardExpMonth(String creditCardExpMonth) {
    this.creditCardExpMonth = creditCardExpMonth;
  }

  public String getCreditCardExpYear() {
    return creditCardExpYear;
  }

  public void setCreditCardExpYear(String creditCardExpYear) {
    this.creditCardExpYear = creditCardExpYear;
  }

  public String getCreditCardSecCode() {
    return creditCardSecCode;
  }

  public void setCreditCardSecCode(String creditCardSecCode) {
    this.creditCardSecCode = creditCardSecCode;
  }

  public boolean isAdmin() {
    return admin;
  }

  public void setAdmin(boolean admin) {
    this.admin = admin;
  }

  @Override
  public int hashCode() {
    final int prime = 31;
    int result = 1;
    result = prime * result
        + ((billingAddress == null) ? 0 : billingAddress.hashCode());
    result = prime
        * result
        + ((creditCardExpMonth == null) ? 0 : creditCardExpMonth
            .hashCode());
    result = prime
        * result
        + ((creditCardExpYear == null) ? 0 : creditCardExpYear
            .hashCode());
    result = prime * result
        + ((creditCardNum == null) ? 0 : creditCardNum.hashCode());
    result = prime
        * result
        + ((creditCardSecCode == null) ? 0 : creditCardSecCode
            .hashCode());
    result = prime * result
        + ((currentAddress == null) ? 0 : currentAddress.hashCode());
    result = prime * result + ((email == null) ? 0 : email.hashCode());
    result = prime * result
        + ((firstName == null) ? 0 : firstName.hashCode());
    result = prime * result
        + ((lastName == null) ? 0 : lastName.hashCode());
    result = prime * result
        + ((password == null) ? 0 : password.hashCode());
    result = prime * result
        + ((phoneNumber == null) ? 0 : phoneNumber.hashCode());
    result = prime * result + (admin ? 1231 : 1237);
    return result;
  }

  @Override
  public boolean equals(Object obj) {
    if (this == obj)
      return true;
    if (obj == null)
      return false;
    if (getClass() != obj.getClass())
      return false;
    User other = (User) obj;
    if (billingAddress == null) {
      if (other.billingAddress != null)
        return false;
    } else if (!billingAddress.equals(other.billingAddress))
      return false;
    if (creditCardExpMonth == null) {
      if (other.creditCardExpMonth != null)
        return false;
    } else if (!creditCardExpMonth.equals(other.creditCardExpMonth))
      return false;
    if (creditCardExpYear == null) {
      if (other.creditCardExpYear != null)
        return false;
    } else if (!creditCardExpYear.equals(other.creditCardExpYear))
      return false;
    if (creditCardNum == null) {
      if (other.creditCardNum != null)
        return false;
    } else if (!creditCardNum.equals(other.creditCardNum))
      return false;
    if (creditCardSecCode == null) {
      if (other.creditCardSecCode != null)
        return false;
    } else if (!creditCardSecCode.equals(other.creditCardSecCode))
      return false;
    if (currentAddress == null) {
      if (other.currentAddress != null)
        return false;
    } else if (!currentAddress.equals(other.currentAddress))
      return false;
    if (email == null) {
      if (other.email != null)
        return false;
    } else if (!email.equals(other.email))
      return false;
    if (firstName == null) {
      if (other.firstName != null)
        return false;
    } else if (!firstName.equals(other.firstName))
      return false;
    if (lastName == null) {
      if (other.lastName != null)
        return false;
    } else if (!lastName.equals(other.lastName))
      return false;
    if (password == null) {
      if (other.password != null)
        return false;
    } else if (!password.equals(other.password))
      return false;
    if (phoneNumber == null) {
      if (other.phoneNumber != null)
        return false;
    } else if (!phoneNumber.equals(other.phoneNumber))
      return false;
    if (!admin != other.admin)
      return false;
    return true;
  }

  @Override
  public String toString() {
    return "User [email=" + email + ", password=" + password
        + ", firstName=" + firstName + ", lastName=" + lastName
        + ", phoneNumber=" + phoneNumber + ", currentAddress="
        + currentAddress + ", billingAddress=" + billingAddress
        + ", creditCardNum=" + creditCardNum + ", creditCardExpMonth="
        + creditCardExpMonth + ", creditCardExpYear="
        + creditCardExpYear + ", creditCardSecCode="
        + creditCardSecCode + ", admin=" + admin + "]";
  }

  /**
   * Encrypts the string and returns the byte array of encrypted data.
   * Returns null if unable to encrypt the string. 
   * @param toEncrypt
   * @return the encrypted byte[]
   * @throws NoSuchAlgorithmException 
   * @throws UnsupportedEncodingException 
   */
  public static byte[] encryptString( String toEncrypt ) throws NoSuchAlgorithmException, UnsupportedEncodingException
  {
    MessageDigest md = MessageDigest.getInstance("MD5");

    byte[] encrypted =  md.digest( toEncrypt.getBytes("UTF-8") );
    md.reset();

    return encrypted;
  }

  public static String createAddressString( String address1, String address2, String address3, String city, String state, String zip )
  {
    String fullAddress = "addr1" + address1 + "%%addr2" + address2 + "%%addr3" + address3 +
        "%%city" + city + "%%state" + state + "%%zip" + zip;

    return fullAddress;
  }

  /**
   * Accepts a fieldName of the following values:
   * addr1, addr2, addr3, city, state, zip
   * 
   * @param fieldName
   * @return the value of that field or null if no valid fieldName
   *
   */
  public String getCurrentAddressSubField( String fieldName )
  {
    String[] fields = currentAddress.split( "%%" );

    if ( "addr1".equals( fieldName ) )
    {
      return fields[0].substring( 5 );
    }
    else if ( "addr2".equals( fieldName ) )
    {
      return fields[1].substring( 5 );
    }
    else if ( "addr3".equals( fieldName ) )
    {
      return fields[2].substring( 5 );
    }
    else if ( "city".equals( fieldName ) )
    {
      return fields[3].substring( 4 );
    }
    else if ( "state".equals( fieldName ) )
    {
      return fields[4].substring( 5 );
    }
    else if ( "zip".equals( fieldName ) )
    {
      return fields[5].substring( 3 );
    }

    return null;
  }

  /**
   * Accepts a fieldName of the following values:
   * addr1, addr2, addr3, city, state, zip
   * 
   * @param fieldName
   * @return the value of that field or null if no valid fieldName
   *
   */
  public String getBillingAddressSubField( String fieldName )
  {
    if ( billingAddress != null )
    {
      String[] fields = billingAddress.split( "%%" );
      if ( "addr1".equals( fieldName ) )
      {
        return fields[0].substring( 5 );
      }
      else if ( "addr2".equals( fieldName ) )
      {
        return fields[1].substring( 5 );
      }
      else if ( "addr3".equals( fieldName ) )
      {
        return fields[2].substring( 5 );
      }
      else if ( "city".equals( fieldName ) )
      {
        return fields[3].substring( 4 );
      }
      else if ( "state".equals( fieldName ) )
      {
        return fields[4].substring( 5 );
      }
      else if ( "zip".equals( fieldName ) )
      {
        return fields[5].substring( 3 );
      }
    }
    return null;
  }
}
